package com.tyj.gulimall.product.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.tyj.common.utils.R;
import com.tyj.gulimall.product.entity.SkuImagesEntity;
import com.tyj.gulimall.product.entity.SpuInfoDescEntity;
import com.tyj.gulimall.product.feign.SeckillFeignService;
import com.tyj.gulimall.product.service.*;
import com.tyj.gulimall.product.vo.web.SeckillSkuVo;
import com.tyj.gulimall.product.vo.web.SkuItemSaleAttrVo;
import com.tyj.gulimall.product.vo.web.SkuItemVo;
import com.tyj.gulimall.product.vo.web.SpuItemBaseAttrGroupVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tyj.common.utils.PageUtils;
import com.tyj.common.utils.Query;

import com.tyj.gulimall.product.dao.SkuInfoDao;
import com.tyj.gulimall.product.entity.SkuInfoEntity;
import org.springframework.util.StringUtils;


@Service("skuInfoService")
@Slf4j
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {

    @Autowired
    SkuImagesService skuImagesService;

    @Autowired
    SpuInfoDescService spuInfoDescService;

    @Autowired
    AttrGroupService attrGroupService;

    @Autowired
    SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    ThreadPoolExecutor executor;

    @Autowired
    SeckillFeignService seckillFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(params),
                new QueryWrapper<SkuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void saveSkuInfo(SkuInfoEntity skuInfoEntity) {
        this.baseMapper.insert(skuInfoEntity);
    }

    @Override
    public PageUtils queryByCondition(Map<String, Object> params) {
//        key: '华为',//检索关键字
//                catelogId: 0,
//                brandId: 0,
//                min: 0,
//                max: 0
        QueryWrapper<SkuInfoEntity> wrapper=new QueryWrapper<>();
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key) && !"0".equals(key)){
            wrapper.and((item)->{
            item.eq("sku_id",key).or().like("sku_name",key);
            });
        }

        String catelogId = (String) params.get("catelogId");
        if (!StringUtils.isEmpty(catelogId) && !"0".equals(catelogId)){
            wrapper.eq("catalog_id",catelogId);
        }

        String brandId = (String) params.get("brandId");
        if (!StringUtils.isEmpty(brandId) && !"0".equals(brandId)){
            wrapper.eq("brand_id",brandId);
        }

        String min = (String) params.get("min");
        if (!StringUtils.isEmpty(min)){
            wrapper.ge("price",min);
        }

        String max = (String) params.get("max");
        if (!StringUtils.isEmpty(max) && !"0".equals(max)){
            wrapper.le("price",max);
        }

        IPage<SkuInfoEntity> page=this.page(new Query<SkuInfoEntity>().getPage(params),wrapper);
        return new PageUtils(page);
    }

    @Override
    public List<SkuInfoEntity> getSkuInfoBySpuId(Long spuId) {
        List<SkuInfoEntity> skus = this.list(new QueryWrapper<SkuInfoEntity>().eq("spu_id", spuId));
        return skus;
    }

    @Override
    public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
        SkuItemVo skuItemVo=new SkuItemVo();
        log.debug("主线程开始");
        CompletableFuture<SkuInfoEntity> infoFutrue = CompletableFuture.supplyAsync(() -> {
            log.debug("线程1开始");
            //1. sku基本信息获取  `pms_sku_info`
            SkuInfoEntity info = getById(skuId);
            skuItemVo.setInfo(info);
            log.debug("线程1结束");
            return info;
        }, executor);

        CompletableFuture<Void> saleAttrFuture = infoFutrue.thenAcceptAsync((res) -> {
            //3. sku销售属性 `pms_sku_sale_attr_value`
            log.debug("线程2开始");
            List<SkuItemSaleAttrVo> skuItemSaleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
            skuItemVo.setSaleAttr(skuItemSaleAttrVos);
            log.debug("线程2结束");
        }, executor);

        CompletableFuture<Void> descFuture = infoFutrue.thenAcceptAsync((res) -> {
            //4. 获取spu的介绍 `pms_spu_info_desc`
            log.debug("线程3开始");
            SpuInfoDescEntity spuInfoDesc = spuInfoDescService.getById(res.getSpuId());
            skuItemVo.setDesp(spuInfoDesc);
            log.debug("线程3结束");
        }, executor);

        CompletableFuture<Void> baseAttruture = infoFutrue.thenAcceptAsync((res) -> {
            //5. spu标准属性 `pms_product_attr_value`
            log.debug("线程4开始");
            List<SpuItemBaseAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
            skuItemVo.setGroupAttr(attrGroupVos);
            log.debug("线程4结束");
        }, executor);

        CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
            //2. sku图片信息 `pms_sku_images`
            log.debug("线程5开始");
            List<SkuImagesEntity> images = skuImagesService.getImagesBySkuId(skuId);
            skuItemVo.setImages(images);
            log.debug("线程5结束");
        }, executor);

        CompletableFuture<Void> seckillSku=CompletableFuture.runAsync(()->{
            //查看当前商品的秒杀信息 前端判断是否处于秒杀时段
            R r = seckillFeignService.getSeckillSkuInfo(skuId);
            if (r.getCode() == 0) {
                SeckillSkuVo seckillSkuVo = r.getData(new TypeReference<SeckillSkuVo>() {});
                long current = System.currentTimeMillis();
                //如果返回结果不为空且活动未过期，设置秒杀信息
                if (seckillSkuVo != null&&current<seckillSkuVo.getEndTime()) {
                    skuItemVo.setSeckillSkuVo(seckillSkuVo);
                }
            }
        }, executor);

        log.debug("主线程开始执行get方法");
        //等待所有任务都完成
        CompletableFuture.allOf(saleAttrFuture,descFuture,baseAttruture,imageFuture,seckillSku).get();
        log.debug("主线程开始执行get结束");
        log.debug("主线程结束....");
        return skuItemVo;

    }


}